﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Kiiro.Common.Utility;
using Kiiro.Logging;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Kiiro.Model.Utility;
using WebFeatureIds = Kiiro.Common.Utility.Constants.SPSiteDefinition.WebFeatureIds;

namespace Kiiro.Model.EventHandlers
{
    public class KiiroInstallerSolutionController : SPFeatureReceiver
    {
        public override void FeatureInstalled ( SPFeatureReceiverProperties properties ) { }

        public override void FeatureUninstalling ( SPFeatureReceiverProperties properties ) { }

        public override void FeatureActivated ( SPFeatureReceiverProperties properties )
        {
            LoggingManager.LogMessage ( "TRACE", "Kiiro.InstallerSolutionController FeatureActivated Begin" );

            SPSolution kiiro = SPFarm.Local.Solutions [ "kiiro sitedefinition.wsp" ];

            foreach ( SPWebApplication webApplication in kiiro.DeployedWebApplications.Cast<SPWebApplication> ( ).Where (
                x => !x.IsAdministrationWebApplication ).ToList ( ) )
            {
                EnsureWebConfig ( webApplication );

                foreach ( SPSite site in webApplication.Sites )
                {
                    using ( SPSite systemSite = SPHelpers.GetSystemSite ( site.ID ) )
                    {
                        foreach ( SPWeb web in systemSite.AllWebs )
                        {
                            if ( SPHelpers.IsPortal ( web ) )
                                web.Features.Add ( new Guid ( WebFeatureIds.Portal ), true );
                            else if ( SPHelpers.IsProject ( web ) )
                                web.Features.Add ( new Guid ( WebFeatureIds.Project ), true );

                            web.Dispose ( );
                        }
                    }

                    site.Dispose ( );
                }
            }

            LoggingManager.LogMessage ( "TRACE", "Kiiro.InstallerSolutionController FeatureActivated End\r\n\r\n" );
        }

        public override void FeatureDeactivating ( SPFeatureReceiverProperties properties )
        {
            LoggingManager.LogMessage ( "TRACE", "Kiiro.InstallerSolutionController FeatureDeActivated Begin" );

            SPSolution kiiro = SPFarm.Local.Solutions [ "kiiro sitedefinition.wsp" ];

            foreach ( SPWebApplication webApplication in kiiro.DeployedWebApplications.Cast<SPWebApplication> ( ).Where (
                x => !x.IsAdministrationWebApplication ).ToList ( ) )
            {
                RemoveWebConfig ( webApplication );

                foreach ( SPSite site in webApplication.Sites )
                {
                    using ( SPSite systemSite = SPHelpers.GetSystemSite ( site.ID ) )
                    {
                        foreach ( SPWeb web in systemSite.AllWebs )
                        {
                            if ( SPHelpers.IsPortal ( web ) )
                                web.Features.Remove ( new Guid ( WebFeatureIds.Portal ), true );
                            else if ( SPHelpers.IsProject ( web ) )
                                web.Features.Remove ( new Guid ( WebFeatureIds.Project ), true );

                            web.Dispose ( );
                        }
                    }

                    site.Dispose ( );
                }

                // double check that all Kiiro timer jobs are deleted, just in case of orphan timer jobs
                webApplication.JobDefinitions.Cast<SPJobDefinition> ( )
                    .Where ( x => x.Name.ToLower ( ).Contains ( Constants.AppName.Lower ) )
                    .ToList ( )
                    .ForEach ( delegate ( SPJobDefinition timerJob ) { timerJob.Delete ( ); } );
            }

            LoggingManager.LogMessage ( "TRACE", "Kiiro.InstallerSolutionController FeatureDeActivated End" );
        }

        private void EnsureWebConfig ( SPWebApplication webApplication )
        {
            foreach ( SPWebConfigModification modification in Constants.WebConfigModifications.AllModifications )
            {
                try
                {
                    if ( !webApplication.WebConfigModifications.Contains ( modification ) )
                    {
                        webApplication.WebConfigModifications.Add ( modification );
                        webApplication.Update ( );
                        webApplication.Farm.Services.GetValue<SPWebService> ( ).ApplyWebConfigModifications ( );
                    }
                }
                catch ( Exception ex )
                {
                    ExceptionManagement.ExceptionManager.HandleException ( ex, false );
                }
            }
        }

        private void RemoveWebConfig ( SPWebApplication webApplication )
        {
            List<SPWebConfigModification> modsToRemove = webApplication.WebConfigModifications.Where (
                x => x.Owner == Constants.AppName.Proper ).ToList ( );

            if ( modsToRemove.Count > 0 )
            {
                foreach ( SPWebConfigModification modification in modsToRemove )
                {
                    try
                    {
                        webApplication.WebConfigModifications.Remove ( modification );
                        webApplication.Update ( );
                        webApplication.Farm.Services.GetValue<SPWebService> ( ).ApplyWebConfigModifications ( );
                    }
                    catch ( Exception ex )
                    {
                        ExceptionManagement.ExceptionManager.HandleException ( ex, false );
                    }
                }
            }

        }
    }
}
